#ifndef _SVNODE_
#define _SVNODE_

#define JNRQ 0xFC
#define JNRS 0xFB
#define HLLO 0xFA
#define KPAV 0xF8 
#define NTFY 0xF7
#define CKRQ 0xF6
#define CKRS 0xF5
#define SHRQ 0xEC
#define SHRS 0xEB
#define GTRQ 0xDC
#define GTRS 0xDB
#define STOR 0xCC
#define DELT 0xBC
#define STRQ 0xAC
#define STRS 0xAB
#define neighbors 0x01
#define files 0x02
#define srchFileName 0x01
#define srchSha1 0x02
#define srchKeys 0x03
//#define Reserved 0x00

#include "my570list.hpp"
#include "cs570.h"
#include <list>
using namespace std;

////// part2 functions

void Boot_Write();
void Boot_Load();
int sv_delete(const char*,const char*,const char*,int);
int sv_searchName(string&);
int sv_searchKeys(string&);
int sv_searchSha1(string&);
void parse_meta(const char*);
void remove_index(int);

unsigned char tohex(unsigned char);
int hex_to_int(unsigned char hex[], int count);

///////////Function Definitions

unsigned char* Get_node_inst_id(char*,int,time_t);
unsigned char* GetUOID(unsigned char*,const char*);
int intLength(int);

void print_NeighborList();
void print_SocketList();
//void print_EventQ();

void killSocketList();
void *NonBeacon_Join(void *);

void *serverthread(void *);
void *beaconconnectthread(void *);
void *readthread(void *);
void *writethread(void *);
void *Process_func(void *);
bool eval_Duplicate();
int eval_DBase();
int eval_Global();
int eval_Global1();
bool duplicateNode();

void print_GlobalList();

/////////// Define packets


/// part 2 packets begin

class Store_Elem
{
	public:
		Store_Elem();
	    char* FileName;
		char* MetaName;
		unsigned int MetaSize;
		int TTL;
	    
};


/// part 2 packets end

//NeighborList_Elem

class Boot_Elem
{
	public:
		Boot_Elem();
	    int index;
		char* FileName;
		unsigned char* Key;
		unsigned char* Sha1;
		unsigned char* Nonce;
		unsigned char* FileId;
		int password;
};



class Flood_Elem
{
	public:
		Flood_Elem();
		unsigned short Port;
		unsigned char MessageType;
		unsigned int HostLocation;
		unsigned char* UOID;
		unsigned char TTL;
		unsigned int Distance;
		unsigned char* respUOID;
		unsigned short respPort;
		char* FileName;
		char* Key;
		char* Sha1;
		char* Nonce;
		int password;
};


class GlobalList_Elem
{
	public:
	GlobalList_Elem();
	unsigned short Port;
	list<Flood_Elem*> ListP;
	int Temp;
	int Socket;
	pthread_mutex_t EventQlock;
	pthread_cond_t EventQ_cv;
	unsigned char* UOID;

};

class InitNeighborList_Elem
{
	public:
		InitNeighborList_Elem();
	unsigned short Port;
	unsigned int Distance;
};
////////////////////////////////////

int Duplicate_Event(Flood_Elem*,list<Flood_Elem*>);

///////////////////////////////////

class NeighborList_Elem
{
	public:
    NeighborList_Elem();
	unsigned char* UOID;
    unsigned short HostPort;
};



// HEADER

struct HEADER
{
	unsigned char MessageType;
	unsigned char* UOID;
	unsigned char TTL;
	unsigned char Reserved;
	unsigned int DataLength;
};

// JOIN_MSG

struct JOIN_MSG
{
	unsigned int HostLocation;
	unsigned short HostPort;
	char* HostName;
};

// JOIN_RES

struct JOIN_RES
{
	unsigned char* UOID;
	unsigned int Distance;
	unsigned short HostPort;
	char* HostName;
};

// HELLO_MSG

struct HELLO_MSG
{
	unsigned short HostPort;
	char* HostName;
};

// NTFY_MSG

struct NTFY_MSG
{
	unsigned char ErrorCode;
};

// STATUS_MSG
struct STATUS_MSG
{
	unsigned char StatusType;
};

// SATUS_RES
struct STATUS_RES_neighbors
{
	unsigned char* UOID;
	short HostInfoLength;
	short HostPort;
	char* Hostname;
	int RecordLength;
	unsigned char* Data;
	
};

// CHCK_MSG

// CHCK_RES

struct CHCK_RES
{
	unsigned char* UOID;
};
//STOR_MSG
struct STOR_MSG
{
	unsigned int MetaLength;
	char* MetaData;
	char* DataFile;
};
// SRCH_MSG

struct SRCH_MSG
{
	unsigned char SearchType;
	char* Query;
};

// SRCH_RES

struct SRCH_RES
{
	unsigned char* UOID;
	unsigned int NextLength;
	char* FileLD;
    char* MetaData;
};
////////////////End packet Definitions

class beacon
{
	public:
		const char* BeaconName;
		int BeaconPort;
		beacon();
};

class ini_info
{
	public:
		int Port;
		unsigned int Location;
		const char* HomeDir;
		const char* LogFilename;
		int AutoShutdown;
		int TTL;
		int MsgLifetime;
		int GetMsgLifetime;
		int InitNeighbors;
		int JoinTimeout;
		int KeepAliveTimeout;
		int MinNeighbors;
		int NoCheck;
		float CacheProb;
		float StoreProb;
		float NeighborStoreProb;
		int CacheSize;
		int Retry;

		//My570List* BeaconList=new My570List();
		list<beacon> BeaconList;


		ini_info();
		
};

ini_info* ini_parser(const char*);


#endif // _SVNODE_
